//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include "CUnicodeManger.h"
#include <_pubcrt.h>
#include <stdlib.h>
#include "inc/uclean.h"
#include "local.h"

CUnicodeManger g_UnicodeManger;

EXTERN_C const char* icupub_getDefaultCodepage()
{
	return g_UnicodeManger.GetLocaleCodePage();
}

EXTERN_C PVoid icupub_ReadFile(const char* path)
{
	return g_UnicodeManger.GetFileData(path);
}

CUnicodeManger::CUnicodeManger()
{
}

CUnicodeManger::~CUnicodeManger()
{
    u_cleanup();
}

const char *CUnicodeManger::GetLocaleCodePage()
{
    const char *name = "gb18030";

    if (m_asCodePage.IsEmpty()) {
        ILocaleInfo *pLocaleInfo = NULL;

        ECode ec = CrtFindService(L"localeinfo", (IInterface **)&pLocaleInfo);
        if (FAILED(ec)) return name;

        ec = pLocaleInfo->GetLocaleInfo(LocaleType_Encoding, &m_asCodePage);
        pLocaleInfo->Release();
        if (FAILED(ec) || m_asCodePage.IsEmpty()) return name;
    }

    return m_asCodePage;
}

PVoid CUnicodeManger::GetFileData(const char* path)
{
	ECode ec = NOERROR;
	wchar_t fullname[_MAX_PATH];
	wchar_t temp[_MAX_PATH];
	_strtowcs(temp, path);
    ec = WFullPath(fullname, temp, _MAX_PATH);
    if (FAILED(ec)) {
       return NULL;
    }

	IDiskManager *pDiskMgr = NULL;
	ec = CrtFindService(L"diskmgr", (PInterface *)&pDiskMgr);
    if (FAILED(ec))  return NULL;

	WStringBuf_<_MAX_FNAME> wsbFile;
	IBasicDirectory* pDir = NULL;
	ec = pDiskMgr->AcquireDirInterface(fullname, &pDir, &wsbFile);
	if (FAILED(ec) || (wsbFile.GetLength() == 0)) {
		pDiskMgr->Release();
       	if (pDir) pDir->Release();
       	return NULL;
    }
    pDiskMgr->Release();

    IBasicFile *pFile = NULL;
    ec = pDir->Lookup(wsbFile, &pFile);
    pDir->Release();
    if (FAILED(ec)) {
    	if (pFile) pFile->Release();
        return NULL;
    }

    IAbsoluteIO *iAb = NULL;
    iAb = IAbsoluteIO::Probe(pFile);
    if (iAb) {
        iAb->AddRef();
    }
    pFile->Release();
    if (!iAb) {
    	return NULL;
    }


	Int32 fileLength;
    ec = iAb->GetSize(&fileLength);
	if(FAILED(ec) || fileLength <= 20) {
        iAb->Release();
        return NULL;
    }

	PVoid pFileBuf = malloc(fileLength);
	if (pFileBuf == NULL) {
		iAb->Release();
		return NULL;
	}
	MemoryBuf buf((Byte *)pFileBuf, fileLength);

	ec = iAb->Read(0, fileLength, &buf);
	if(FAILED(ec)) {
		free(pFileBuf);
       	iAb->Release();
        return NULL;
    }

	iAb->Release();

    return buf.GetPayload();
}
